/*
 * Copyright (c) 2001-2018 GuaHao.com Corporation Limited. All rights reserved.
 * This software is the confidential and proprietary information of GuaHao Company.
 * ("Confidential Information").
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the license agreement you entered into with GuaHao.com.
 */
package com.bgt.springboot.first.utils;

/**
 * 修正版
 *
 * @author Ricky
 * @version V 2.0
 * @since 2018-08-22 19:29
 */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntFunction;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.poi.ss.formula.functions.T;

/**
 * Created by baiguantao on 2017/6/13.
 * http线程池管理
 */
public class HttpPerfectUtils {
    private static PoolingHttpClientConnectionManager clientConnectionManager = null;
    private static RequestConfig requestConfig = null;
    // http客户端
    private static HttpClient httpClient = null;

    static {
        HttpProperties properties = new HttpProperties();
        //请求配置 基础超时配置
        requestConfig = RequestConfig.custom().setConnectTimeout(properties.getConnectTimeOut())
            .setConnectionRequestTimeout(properties.getConnectionRequestTimeOut())
            .setSocketTimeout(properties.getSocketTimeOut()).build();
        // 设置socket支持类型
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("https", SSLConnectionSocketFactory.getSocketFactory())
            .register("http", PlainConnectionSocketFactory.getSocketFactory()).build();
        // 生成http连接管理客户端
        clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        // 总可用会话数量
        clientConnectionManager.setMaxTotal(properties.getMaxTotal());
        // 总可用线路，建议与会话保持一致
        clientConnectionManager.setDefaultMaxPerRoute(properties.getDefaultMaxPerRoute());
        // 设置Cookie基础信息
        CookieStore cookieStore = new BasicCookieStore();
        // 设置cookie名称和值 一般是指JSESSIONID
        BasicClientCookie cookie = new BasicClientCookie("sessionID", "######");
        cookie.setDomain("ricky.com");// 设置domain
        cookie.setPath("/index");// 设置path
        cookie.setVersion(1);// 设置版本
        cookieStore.addCookie(cookie);
        // 构建自定义的httpClient
        httpClient = HttpClients.custom().setConnectionManager(clientConnectionManager)
            .setDefaultCookieStore(cookieStore).setDefaultRequestConfig(requestConfig).build();
    }

    /**
     * get方式的http请求
     * @param uri
     * @return
     */
    public static String get(String uri) {
        return get(uri,null);
    }

    /**
     * get方式的http请求
     * @param uri http://www.baidu.com
     * @param header Header对象
     * @return
     */
    public static String get(String uri, Header[] header) {
        StringBuilder result = new StringBuilder();
        HttpGet get = null;
        try {
            // 定义get请求参数配置
            get = new HttpGet(uri);
            get.setHeaders(header);
            // 执行请求 查看响应信息
            HttpResponse resp = httpClient.execute(get);
            getReponseResult(resp,result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != get) {
                //释放连接
                get.releaseConnection();
            }
        }
        return result.toString();
    }
    /**
     * post方式的http请求
     * @param uri http://www.baidu.com
     * @return
     */
    public static String post(String uri) {
        return post(uri,null,null);
    }
    /**
     * post方式的http请求
     * @param uri http://www.baidu.com
     * @param body 格式:"name=XX&idNumber=xxx&userId=xx&phone=xx";
     * @return
     */
    public static String post(String uri,String body) {
        return post(uri,null,body);
    }
    /**
     * post方式的http请求
     *
     * @param uri http://www.baidu.com
     * @param header Header对象
     * @param body  格式:"name=XX&idNumber=xxx&userId=xx&phone=xx";
     * @return
     */
    public static String post(String uri, Header[] header,String body) {
        StringBuilder result = new StringBuilder();
        HttpPost post = null;
        try {
            // 定义post请求参数配置
            post = new HttpPost(uri);
            post.setHeaders(header);
            StringEntity stringEntity = new StringEntity(body, "UTF-8");
            stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "UTF-8"));
            // 设置请求主体
            post.setEntity(stringEntity);

            // 执行请求 查看响应信息
            HttpResponse resp = httpClient.execute(post);
            getReponseResult(resp,result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != post) {
                //释放连接
                post.releaseConnection();
            }
        }
        return result.toString();
    }

    /**
     * 获取响应结果
     * @param resp  HttpResponse 对象
     * @param result  响应结果
     * @return
     */
    private static void getReponseResult(HttpResponse resp, StringBuilder result) {
        try {
            // 响应Code编码
            int statusCode = resp.getStatusLine().getStatusCode();
            // 如果是200 通过
            if (HttpStatus.SC_OK == statusCode) {
                HttpEntity entity = resp.getEntity();

                BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                while (-1!=br.read()) {
                    result.append(br.readLine());
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<Header> addHeaders(Header header,List<Header> headers){
        if (null==headers) {
            headers=new ArrayList<>();
        }
        headers.add(header);
        return headers;
    }


    public static void main(String[] args) {
        String resultStr = HttpPerfectUtils.get("http://wwww.baidu.com",
            new HttpHeaders().addHeaders("Accept", "*/*")
                .getHeadersArray());
        System.out.println(resultStr);

    }
}

/**
 * Http基础参数
 */
class HttpProperties {
    // 连接超时时间
    private int connectTimeOut = 5000;
    //请求超时时间
    private int connectionRequestTimeOut = 1000;
    //socket超时时间
    private int socketTimeOut = 1000;
    //总会话数
    private int maxTotal = 50;
    //socket超时时间
    private int defaultMaxPerRoute = 50;

    public int getConnectTimeOut() {
        return connectTimeOut;
    }

    public void setConnectTimeOut(int connectTimeOut) {
        this.connectTimeOut = connectTimeOut;
    }

    public int getConnectionRequestTimeOut() {
        return connectionRequestTimeOut;
    }

    public void setConnectionRequestTimeOut(int connectionRequestTimeOut) {
        this.connectionRequestTimeOut = connectionRequestTimeOut;
    }

    public int getSocketTimeOut() {
        return socketTimeOut;
    }

    public void setSocketTimeOut(int socketTimeOut) {
        this.socketTimeOut = socketTimeOut;
    }

    public int getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public int getDefaultMaxPerRoute() {
        return defaultMaxPerRoute;
    }

    public void setDefaultMaxPerRoute(int defaultMaxPerRoute) {
        this.defaultMaxPerRoute = defaultMaxPerRoute;
    }
}

/**
 * http请求头封装
 */
class HttpHeaders{
    private List<Header> headers;
    public HttpHeaders(List<Header> headers) {
        if (null==headers) {
            headers=new ArrayList<>();
        }
        this.headers= headers;
    }
    public HttpHeaders() {
        this.headers= new ArrayList<>();
    }
    public  HttpHeaders addHeaders(Header header){
        headers.add(header);
        return this;
    }
    public  HttpHeaders addHeaders(String name,String value){
        headers.add(new BasicHeader(name,value));
        return this;
    }

    public List<Header> getHeaders() {
        return headers;
    }

    /**
     * 转为Header数组
     * @return
     */
    public Header[] getHeadersArray() {
        return  headers.toArray(new Header[headers.size()]);
    }
}


